package org.andao.core.base.controller;

import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.andao.core.exception.WebException;
import org.andao.core.utils.ExStringUtils;
import org.andao.core.utils.HttpServletUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContext;


/**
 * Controller基类,封装了render. <p>
 *
 * @author Seewo software - Marco.hu(huzhiguo@cvte.cn)
 * @build 2013-6-21下午8:28:01
 */
public abstract class BaseSupportController extends BinderSupportController {
	
	private static final long serialVersionUID = -5568039278783942375L;

	protected static Logger logger = LoggerFactory.getLogger(BaseSupportController.class);
	
	protected Map<String,Object> result = new HashMap<String,Object>();
	
	protected static final String STATUS_CODE = "statusCode";
	
	protected static final String MESSAGE = "message";
	
	protected static final String MODEL_CONDITION = "condition";
	
	/**错误信息最大长度，如果大于这个长度，则判断为系统错误信息，直接显示:"Sorry, 404"。否则显示此错误信息*/
	protected static final int MESSAGE_MAX_SIZE = 100;
	
	protected static final int SUCCESS = 200;
	
	protected static final int ERROR = 300;
	
	/*进行操作后，页面是否重新加载*/
	public static final boolean ISRELOAD = true;	
	
	/*搜索表单域前缀*/
	public static final String QUERY_PREFIX = "search_";
	
	/*resourceids 分隔符*/
	public static final String SPLIT_COMMA = ",";
		
	//记录ID集合，用于批量更新/审核等情况
	public List<Serializable> resourceid;		
	
	//返回前台页面的操作结果
	protected Map<String,Object> resultMap = new HashMap<String,Object>(0);
	
	//操作结果枚举
	public enum OpratorResult{
		SUCCESS_RELOAD,
		SUCCESS_FORWARD,
		FAILD
	}
	
	public List<Serializable> getResourceid() {
		return resourceid;
	}

	public void setResourceid(List<Serializable> resourceid) {
		this.resourceid = resourceid;
	}

	/**
	 * 直接输出文本.
	 * @see #render(String, String, String...)
	 */
	protected static void renderText(HttpServletResponse response ,final String text, final String... headers) {
		HttpServletUtils.render(response,"text/plain", text, headers);
	}

	/**
	 * 直接输出HTML.
	 * @see #render(String, String, String...)
	 */
	protected static void renderHtml(HttpServletResponse response,final String html, final String... headers) {
		HttpServletUtils.render(response,"text/html", html, headers);
	}

	/**
	 * 直接输出XML.
	 * @see #render(String, String, String...)
	 */
	protected static void renderXml(HttpServletResponse response,final String xml, final String... headers) {
		HttpServletUtils.render(response,"text/xml", xml, headers);
	}

	/**
	 * 直接输出JSON.
	 * 
	 * @param string json字符串.
	 * @see #render(String, String, String...)
	 */
	protected static void renderJson(HttpServletResponse response,final String string, final String... headers) {
		HttpServletUtils.render(response,"application/json", string, headers);
	}
	/**
	 * 直接输出Excel
	 * @param response
	 * @param string
	 * @param headers
	 * @see #render(String, String, String...)
	 */
	protected static void renderExcel(HttpServletResponse response,final String string,final String... headers){
		HttpServletUtils.render(response,"application/ms-excel", string, headers);
	}
	
	/**
	 * 直接输出为pdf文档.
	 * @param response
	 * @param string
	 * @param headers
	 */
	protected static void renderPdf(HttpServletResponse response,final String string,final String... headers){
		HttpServletUtils.render(response,"application/pdf", string, headers);
	}
	
	/**
	 * 输出对象为数据流
	 * @param response
	 * @param obj
	 */
	protected static void renderStream(HttpServletResponse response, Object obj){
		response.setContentType("application/octet-stream");
		try {
			ServletOutputStream ouputStream = response.getOutputStream();			
			ObjectOutputStream oos = new ObjectOutputStream(ouputStream);
			oos.writeObject(obj);
			oos.flush();
			
			ouputStream.flush();
			ouputStream.close();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		}finally{		
			obj = null;
		}
		
	}
	
	/**
	 * 获取web root context.
	 * @param request
	 * @return
	 */
	protected String getRootUrl(HttpServletRequest request){
		return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort();
	}
	
	/**
	 * 获取web context.
	 * @param request
	 * @return
	 */
	protected String getBaseUrl(HttpServletRequest request){
		return request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath();
	}
	
	/**
	 * 统一异常处理(异常捕捉)
	 * @param request
	 * @param response
	 * @param handler 异常handler
	 * @param ex 异常
	 * @return
	 */
	protected ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		Map<String,Object> model = new HashMap<String,Object>();
		model.put("errHandle", handler.getClass().getSimpleName());
        model.put("ex", ex.getClass().getSimpleName());
        model.put("error", ex.fillInStackTrace());
     
        return new ModelAndView("/common/error", model);
       
	}	
	
	/**
	 * 返回页面的操作结果.
	 * @param ctx 
	 * @param result
	 * @param reloadPageUrl
	 * @param message
	 * @return
	 */
	protected Map<String,Object> opratorResult(RequestContext ctx, OpratorResult result,String reloadPageUrl,String message){	
		Map<String,Object> resultMap = new HashMap<String,Object>(0);
		if(result.equals(OpratorResult.FAILD)){
			resultMap.put("statusCode", 300);
			resultMap.put("message", (ExStringUtils.isNotBlank(message)) ? message:ctx.getMessage("OPERATE_FAIL"));
		}else{
			resultMap.put("statusCode", 200);
			resultMap.put("message", (ExStringUtils.isNotBlank(message)) ? message:ctx.getMessage("OPERATE_SUCCESS"));
			resultMap.put((result.equals(OpratorResult.SUCCESS_FORWARD))?"forword":"reloadUrl",reloadPageUrl);
			
		}
		return resultMap;
	}

	/**
	 * 绑定查询条件参数
	 * @param condition
	 * @param request
	 * @param parameter
	 * @return
	 */
	protected Map<String,Object> bindQueryCondition(Map<String,Object> condition,HttpServletRequest request,String ... parameters){
		if(null == condition) 
			throw new WebException("条件Map不能为空.");
		if(null != parameters){
			for(String p : parameters){
				String[] ps = ExStringUtils.split(p, "_");				
				String v = ExStringUtils.trimToEmpty(request.getParameter(ps[1]));
				if(ExStringUtils.isNotBlank(v)){
					condition.put(p, v);
				}
			}
		}
		return condition;
	}
	/**
	 * 获取错误信息，如果错误信息大于 MESSAGE_MAX_SIZE 则直接显示“Sorry, 404”，防止向用户界面抛出系统错误信息
	 * @notice 仅用于向用户输出信息，切勿用于写日志
	 * @param e 异常
	 * @return
	 * @brief
	 * @author Seewo Software - Vick.liu (liuguanglin@cvte.cn)
	 */
	protected String getErrorMessage(Exception e){
		return  e.getMessage().length() > MESSAGE_MAX_SIZE ? "Sorry, 404" : e.getMessage();
	}
}
